/***************************************************************************
 *  Filename: processmanager.h
 *  Class: ProcessManager
 *
 *  Copyright 2012  Xander van Kooten
 *  <xandervk@gmail.com>
 *
 *  Copyright 2012  Mario Henrique Voorsluys
 *  <forcaeluz@gmail.com>
 *
 ****************************************************************************/

/*
 *
 * This file is part of Parsax-Remote-Controller.
 *
 *    Parsax-Remote-Controller is free software: you can redistribute it
 *    and/or modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    Parsax-Remote-Controller is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Parsax-Remote-Controller.
 *    If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef PROCESSMANAGER_H
#define PROCESSMANAGER_H

#include <QObject>
#include <QProcess>
#include <QTimer>

/*!
 \brief Manage the process (Start/Stop) and handles communication (Status/CLO).

 The ProcessManager is responsible for starting and stopping the remote controlled process.
 It provides also the possibility to send status updates to the master and also the program
 command line output.

 In the future this class could be expanded to support sending commands to the program,
 increasing the number of status messages (Currently only 3 are supported) and also
 implementing a timer function that sends a heartbeat message that could be monitored by
 the master.


 \todo Heartbeat function to send status messages every t ms.
 \todo More status messages specifying error types, or messages generated in this class
 and not in the QProcess object.
 \todo Send command line input to the program.

*/
class ProcessManager : public QObject
{
    Q_OBJECT
public:

    /*!
     \brief ProcessManager Constructor

     \param tid The ID of this process. (Not the OS pid)
     \param parent QObjects parent.

     The constructor initializes the id variable. The id is to identify this ProcessManager
     by the master computer, and is not the OS process id. By using this ID the master can tell
     this process to stop and start. It's possible to give friendly names as ID, the only
     requirement is that they should be unique.
    */
    explicit ProcessManager(QString tid, QObject *parent = 0);

    /*!
     \brief

    */
    ~ProcessManager();
    /*!
     \brief Set the program that should be started

     \param tprogram The program (As it would be started from the slave command line)

     Sets the string "program" as the program should be started.

     \list Linux Examples:
     \li /usr/bin/gcc
     \li gcc

     \list Windows Examples:
     \li C:\Program Files\Program\program.exe
     \li notepad.exe
    */
    void setProgram(QString tprogram);

    /*!
     \brief Set the parameters (arguments) given to the program at startup.

     \param tparams The arguments list.

     Arguments usually given to a program started in command line.
    */
    void setParameters(QStringList tparams);

    /*!
     \brief Read variable function.

     \return QString The program that should be started
    */
    QString getProgram();

    /*!
     \brief Read variable function.

     \return QString The parameters to start the program.
    */
    QString getParameters();

    /*!
     \brief Read variable function.

     \return QString Process status.
    */
    QString getStatus();

    /*!
     \brief Start the process.

     Checks if the process is running. If not, the process is started.
    */
    void start();

    /*!
     \brief Stop the process.

     Checks if the process is running. It it is, the process is stopped.
    */
    void stop();

    /*!
     \brief Stops and restarts the process.

     If the process is not running, it starts running.
    */
    void restart();

    /*!
     \brief

     \param cmd
    */
    void sendCmdToProcess(QString cmd);
signals:

    /*!
     \brief Emitted when the process sends command line output.

     \param tid The Id given to the program.
     \param type Message type.(Normal=0, Error=1)
     \param msg The message itself.
    */
    void cloReceived(QString tid, int type, QString msg);

    /*!
     \brief Emitted when a status should be sent.

     \param tid The Id given to the program.
     \param status The process status (starting/running/notrunning).
    */
    void statusReceived(QString tid, QString status);
public slots:

private:
    QProcess myProcess; /*!< QProcess that actually starts stops and monitore the application */
    QString id; /*!< The process id */
    QString program; /*!< The program that should be started */
    QStringList params; /*!< List with start arguments */
    QTimer myTimeKeeper; /*!< Timer to be used for heartbeat */

private slots:

    /*!
     \brief Send status messages.

    */
    void sendStatus();

    /*!
     \brief Send CLO messages.

    */
    void sendClo();

    /*!
     \brief Send CLE messages. (CLO error messages).

    */
    void sendCle();
};

#endif // PROCESSMANAGER_H
